#include <QUrl>
#include <QNetworkReply>
#include <QRegExp>
#include <QEventLoop>
#include "oxford-loader.h"
#include "network-error.h"

using namespace Oxford;

Loader::Loader()
{
}

QStringList Oxford::Loader::loadOxford3000LettersList()
{
    QNetworkReply *reply = http.get(QNetworkRequest(QUrl("http://www.oxfordadvancedlearnersdictionary.com/oxford3000/")));

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QString page = reply->readAll();

    if (reply->error() != QNetworkReply::NoError)
        throw new Core::ENetworkError("An error occured during loading Oxford 3000 page");

    QStringList result;
    QRegExp rx("<li class=\"currentpage\"><span class=\"pad5\">([^<]+)</span></li>");
    rx.setMinimal(true);

    if (page.contains(rx))
        result << rx.cap(1);

    rx.setPattern("<li><a href=\"/oxford3000/[^\"]+/\">([^<]+)</a></li>");

    int pos = 0;
    while ((pos = rx.indexIn(page, pos)) >= 0)
    {
        result << rx.cap(1);
        pos += rx.matchedLength();
    }

    return result;
}

QStringList Loader::loadOxford3000ListPage(const QString& letters, int pageId)
{
    QNetworkReply *reply = http.get(QNetworkRequest(QUrl(QString("http://www.oxfordadvancedlearnersdictionary.com/oxford3000/ox3k_%1/?page=%2").arg(letters).arg(pageId))));

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QString page = reply->readAll();

    if (reply->error() != QNetworkReply::NoError)
        throw new Core::ENetworkError(QString("An error occured during loading Oxford 3000 List page: %1").arg(reply->errorString()));

    QStringList result;
    QRegExp rx("<a href=\"/dictionary/([^\"]+)\"");
    int pos = 0;
    while ((pos = rx.indexIn(page, pos)) >= 0)
    {
        result << rx.cap(1);
        pos += rx.matchedLength();
    }

    return result;
}

QStringList Oxford::Loader::loadWordRangesForLetter(char letter)
{
    QNetworkReply *reply = http.get(QNetworkRequest(QUrl(QString("http://www.oxfordadvancedlearnersdictionary.com/browse/%1/").arg(letter))));

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QString page = reply->readAll();

    if (reply->error() != QNetworkReply::NoError)
        throw new Core::ENetworkError(QString("An error occured during loading Oxford page: %1").arg(reply->errorString()));

    QStringList result;
    QRegExp rx(QString("<a href=\"/browse/%1/([^/]+)/\"").arg(letter));
    int pos = 0;
    while ((pos = rx.indexIn(page, pos)) >= 0)
    {
        result << rx.cap(1);
        pos += rx.matchedLength();
    }

    return result;
}

QStringList Oxford::Loader::loadWordsInRange(char letter, const QString &rangeLink)
{
    QNetworkReply *reply = http.get(QNetworkRequest(QUrl(QString("http://www.oxfordadvancedlearnersdictionary.com/browse/%1/%2/").arg(letter).arg(rangeLink))));

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QString page = reply->readAll();

    if (reply->error() != QNetworkReply::NoError)
        throw new Core::ENetworkError(QString("An error occured during loading Oxford page: %1").arg(reply->errorString()));

    QStringList result;
    QRegExp rx("<a href=\"/dictionary/([^\"]+)\"");
    int pos = 0;
    while ((pos = rx.indexIn(page, pos)) >= 0)
    {
        result << rx.cap(1);
        pos += rx.matchedLength();
    }

    return result;
}

QString Loader::loadWord(const QString &word)
{    
    QNetworkReply *reply = http.get(QNetworkRequest(QUrl(QString("http://www.oxfordadvancedlearnersdictionary.com/dictionary/%1").arg(word))));

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    loop.exec();

    QString page = QString::fromUtf8(reply->readAll().data());

    if (reply->error() != QNetworkReply::NoError)
        throw new Core::ENetworkError(QString("An error occured during loading Oxford word page: %1").arg(reply->errorString()));

    return page;
}
